package de.nabble;

import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.UIManager;

import de.nabble.events.EventHandler;
import de.nabble.gui.BoardPanel;
import de.nabble.gui.ColorTheme;
import de.nabble.gui.MainFrame;
import de.nabble.gui.PointsPanel;
import de.nabble.gui.RowPanel;
import de.nabble.model.GameBoard;
import de.nabble.model.LetterBag;
import de.nabble.model.LetterRow;
import de.nabble.model.Model;
import de.nabble.model.Player;
import de.nabble.util.Helper;

/**
 * --------------------------------------------------------------------------
 * READ ME FIRST:
 * Use one of the three log methods of this class to write to the logtarget. 
 * --------------------------------------------------------------------------
 * 
 * Entrypoint for Nabble.
 * 
 * @author Tom
 */
public class Nabble {

	/**
	 * Path to language bundle.
	 */
	public static String RESOURCE_PATH = "i18n/lang_de";
	
	/**
	 * Path to the letterbundle.
	 */
	public static String LETTER_BUNDLE_PATH = "i18n/letters_de";
	
	/**
	 * Holds all colors for the game.
	 * 
	 * @deprecated hat hier nichts zu suchen. theme objekt bei bedarf
	 * mittels ColorTheme.getInstance() holen.
	 */
	@Deprecated
	public static ColorTheme COLOR_THEME = ColorTheme.getInstance();
	
	/**
	 * Defines if logging is active.
	 */
	private static final boolean LOG_ACTIVE = true;
	
	/**
	 * Defines the logtarget. Default is System.out.
	 * Another option could be a log file ...
	 */
	private static final PrintStream LOG_TARGET = System.out;

	/**
	 * path to wordfile.
	 */
	public static final String WORD_FILE = "src/words/words.german";
	
	/*
	 * Calling the UIManager to set up the system lookandfeel.
	 */
	static {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			log("Exception when calling the UIManager: ", e);

		}
		System.out.println("Lines of code in project without comments: " + Helper.getProjectLinesOfCode("D:/java-workspace/nabbleSvnCheckOutTest", ".java", false) 
				+ "\nLines of code in project with comments: " + Helper.getProjectLinesOfCode("D:/java-workspace/nabbleSvnCheckOutTest", ".java", true));
	}
	
	/**
	 * Main method. Objectcreating, preparing and starting the application.
	 * @param args command line arguments.
	 */
	public static void main(String[] args) {
		
		GameBoard board = new GameBoard();
		LetterBag bag = new LetterBag();
		
		LetterRow row = new LetterRow(bag);
		Player player = new Player("Tom", row);
		
		Model model = new Model(board);
		model.addPlayer(player);
		
		setSomeStones(true, bag, board);		
		
		EventHandler handler = new EventHandler(board, row);
		
		BoardPanel panel = new BoardPanel(board, handler);
		PointsPanel points = new PointsPanel(model.getPlayers());
		
		RowPanel rowPa = new RowPanel(row.getLetters(), handler);
		
		handler.setPanels(panel, rowPa);
		
		MainFrame f = new MainFrame(panel, points, rowPa);
		f.setVisible(true);
		f.setHandler(handler);
		
	}
	
	/**
	 * Helpermethode
	 * @param on
	 * @param bag
	 * @param board
	 */
	private static void setSomeStones(boolean on, LetterBag bag, GameBoard board) {
		if(on) {
			
			board.setLetterOnField(bag.getSpecificLetter('b'), 1, 1);
			board.setLetterOnField(bag.getSpecificLetter('a'), 1, 2);
			board.setLetterOnField(bag.getSpecificLetter('l'), 1, 3);
			board.setLetterOnField(bag.getSpecificLetter('l'), 1, 4);
			
			board.setLetterOnField(bag.getSpecificLetter('k'), 6, 7);
			board.setLetterOnField(bag.getSpecificLetter('r'), 7, 7);
			board.setLetterOnField(bag.getSpecificLetter('a'), 8, 7);
			board.setLetterOnField(bag.getSpecificLetter('u'), 9, 7);
			board.setLetterOnField(bag.getSpecificLetter('t'), 10, 7);
			
			board.setLetterOnField(bag.getSpecificLetter('a'), 5, 9);
			board.setLetterOnField(bag.getSpecificLetter('p'), 6, 9);
			board.setLetterOnField(bag.getSpecificLetter('f'), 7, 9);
			board.setLetterOnField(bag.getSpecificLetter('e'), 8, 9);
			board.setLetterOnField(bag.getSpecificLetter('l'), 9, 9);
//			board.setLetterOnField(bag.getSpecificLetter('e'), 10, 9);
			
//			board.setLetterOnField(bag.takeLetter(), 12, 12);
//			board.setLetterOnField(bag.takeLetter(), 12, 13);
//			board.setLetterOnField(bag.takeLetter(), 13, 12);
//			board.setLetterOnField(bag.takeLetter(), 11, 12);
		}
	}
	
	/**
	 * Use this method instead of System.out.println()
	 * @param msg The message to log.
	 * @see Nabble#log(Object, Throwable)
	 */
	public static void log(Object msg) {
		log(msg, null);
	}
	
	/**
	 * Use this method instead Exception#printStackTrace();
	 * @param thr for use in catch-clause.
	 * @see Nabble#log(Object, Throwable)
	 */
	public static void log(Throwable thr) {
		log(null, thr);
	}
	
	/**
	 * Use this method instead of Syso. 
	 * @param msg the msg to log. Type Object is used to get the toString()
	 * output of an object.
	 * @param thr for use in catch-clause.
	 */
	public static void log(Object msg, Throwable thr) {
		if (!LOG_ACTIVE) {
			return;
		}
		
		Date now = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat();
		String logStr = "[" + sdf.format(now) + "] ";
		
		if(msg != null) {
			logStr += msg;
			LOG_TARGET.println(logStr);
		}
		
		if(thr != null) {
			if(msg == null) {
				logStr += thr.getClass().getSimpleName() + " catched:";
				LOG_TARGET.println(logStr);
			}
			thr.printStackTrace(LOG_TARGET);
		}
	}
}
